/*
 * KKScheduler.h
 *
 *  Created on: 2013-9-23
 *      Author: wanghua
 */

#ifndef KKSCHEDULER_H_
#define KKSCHEDULER_H_

#include "kaka_common.h"
#include "KKCallback.h"
USING_NS_CC;

using namespace std;

class KKSchedulerTask: public KKCallback {

public:
	KKSchedulerTask(CCObject* target, SEL_CallFuncO callback, CCObject* args) :
			KKCallback(target, callback, args) {
	}
	;

	virtual ~KKSchedulerTask() {
		cancel();
	}
	;

public:
	void cancel() {
		CCDirector::sharedDirector()->getScheduler()->unscheduleAllForTarget(
				this);
	}
	;

	void execute(ccTime time) {
		CCDirector::sharedDirector()->getScheduler()->unscheduleAllForTarget(
				this);
		(this->target->*callback)(args);
	}
	;
};

class KKTaskKey {
public:
	long target;
	long callback;

	KKTaskKey(CCObject* target, SEL_CallFuncO callback) {
		this->target = long(target);
		this->callback = *((long*) (&callback));
	}

	virtual ~KKTaskKey() {
		target = NULL;
		callback = NULL;
	}

	bool operator>(const KKTaskKey &p) const {
		return target > p.target
				|| (target == p.target && callback > p.callback);
	}

	bool operator<(const KKTaskKey &p) const {
		return target < p.target
				|| (target == p.target && callback < p.callback);
	}

	bool operator==(const KKTaskKey &p) const {
		return target == p.target && callback == p.callback;
	}
};

class KKScheduler: public CCObject {
private:

	static KKScheduler* m_instance;

	KKDictionary<KKTaskKey, KKSchedulerTask*> m_tasks;

public:
	KKScheduler();
	virtual ~KKScheduler();

	static KKScheduler* sharedScheduler() {

		if (!m_instance) {
			m_instance = new KKScheduler();
		}
		return m_instance;
	}

	void pause(CCObject* target, SEL_CallFuncO callback);

	void resume(CCObject* target, SEL_CallFuncO callback);

	void schedule(CCObject* target, SEL_CallFuncO callback, ccTime delay,
			CCObject* args = NULL);

	void cancel(CCObject* target, SEL_CallFuncO callback);
};
#endif /* KKSCHEDULER_H_ */
